#include "caudioitem.h"
#include "crootwindow.h"

#include <buola/image/cimage.h>
#include <buola/image/cgc.h>
#include <buola/media/cmixer.h>

namespace buola { namespace bdesktop {

CAudioItem::CAudioItem()
{
    mMixer=&media::get_simple_mixer();
    mMixer->eChange.Connect(&CAudioItem::OnMixer,this,_1);
    mValue=mMixer->GetVolume(mMixer->GetMasterElement());
    mMuted=mMixer->GetMute(mMixer->GetMasterElement());
    
    mVolUp.Set(KEY_VOLUMEUP,KEYMOD_NONE,gui::CAccelerator::GLOBAL,gRootWindow);
    mVolUp.eTriggered.Connect(std::bind(&CAudioItem::OnVolumeKey,this,0.05));
    mVolDown.Set(KEY_VOLUMEDOWN,KEYMOD_NONE,gui::CAccelerator::GLOBAL,gRootWindow);
    mVolDown.eTriggered.Connect(std::bind(&CAudioItem::OnVolumeKey,this,-0.05));
    mVolMute.Set(KEY_AUDIOMUTE,KEYMOD_NONE,gui::CAccelerator::GLOBAL,gRootWindow);
    mVolMute.eTriggered.Connect(std::bind(&CAudioItem::OnVolumeMute,this));
}

CAudioItem::~CAudioItem()
{
}

void CAudioItem::DrawSpeaker(CGC *pGC,bool pShadow)
{
    double lC=round((mPos.t+mPos.b)/2)-1.0;
    if(pShadow)
        pGC->SetSourceColor(CColor(0.1,0.1,0.1));
    else if(mValue>0&&!mMuted)
        pGC->SetSourceColor(CColor(0.9,0.9,0.9));
    else
        pGC->SetSourceColor(CColor(0.5,0.5,0.5));
    pGC->MoveTo(CPoint(mPos.l+4,lC-2));
    pGC->LineTo(CPoint(mPos.l+4,lC+2));
    pGC->LineTo(CPoint(mPos.l+7,lC+2));
    pGC->LineTo(CPoint(mPos.l+10,lC+5));
    pGC->LineTo(CPoint(mPos.l+10,lC-5));
    pGC->LineTo(CPoint(mPos.l+7,lC-2));
    pGC->ClosePath();
    pGC->FillPath();
    pGC->SetLineWidth(1.0);

    if(pShadow)
        pGC->SetSourceColor(CColor(0.1,0.1,0.1));
    else if(mValue>=0.28&&!mMuted)
        pGC->SetSourceColor(CColor(0.9,0.9,0.9));
    else
        pGC->SetSourceColor(CColor(0.5,0.5,0.5));
    
    pGC->Arc(CPoint(mPos.l+11,lC),2,-M_PI*0.4,M_PI*0.4);
    pGC->StrokePath();

    if(pShadow)
        pGC->SetSourceColor(CColor(0.1,0.1,0.1));
    else if(mValue>=0.56&&!mMuted)
        pGC->SetSourceColor(CColor(0.9,0.9,0.9));
    else
        pGC->SetSourceColor(CColor(0.5,0.5,0.5));
    
    pGC->Arc(CPoint(mPos.l+11,lC),5,-M_PI*0.35,M_PI*0.35);
    pGC->StrokePath();

    if(pShadow)
        pGC->SetSourceColor(CColor(0.1,0.1,0.1));
    else if(mValue>=0.84&&!mMuted)
        pGC->SetSourceColor(CColor(0.9,0.9,0.9));
    else
        pGC->SetSourceColor(CColor(0.5,0.5,0.5));
    
    pGC->Arc(CPoint(mPos.l+11,lC),8,-M_PI*0.3,M_PI*0.3);
    pGC->StrokePath();
}

double CAudioItem::GetWidth()
{
    return 24;
}

void CAudioItem::Draw(CGC *pGC)
{
    pGC->Translate(CPoint(1,1));
    DrawSpeaker(pGC,true);
    pGC->Translate(CPoint(-1,-1));
    DrawSpeaker(pGC,false);
}

void CAudioItem::OnClick(gui::CMouseEvent *pE)
{
    if(pE->mButton==gui::MOUSE_ZUP)
    {
        OnVolumeKey(0.02);
    }
    else if(pE->mButton==gui::MOUSE_ZDOWN)
    {
        OnVolumeKey(-0.02);
    }
    else if(pE->mButton==gui::MOUSE_MIDDLE)
    {
        OnVolumeMute();
    }
}

void CAudioItem::OnMixer(media::CMixer::TElement pElement)
{
    if(pElement!=mMixer->GetMasterElement()) return;
    
    double lValue=mMixer->GetVolume(pElement);
    bool lMuted=mMixer->GetMute(mMixer->GetMasterElement());
    if(lValue==mValue&&lMuted==mMuted) return;
    mValue=lValue;
    mMuted=lMuted;

    if(mBar) mBar->Refresh();
}

void CAudioItem::OnVolumeKey(double pChange)
{
    double lNewValue=clamp(mValue+pChange,0.0,1.0);
    if(mMuted)
    {
        mMixer->SetMute(mMixer->GetMasterElement(),false);
        mMuted=false;
        mBar->Refresh();
    }
    if(lNewValue!=mValue)
    {
        mMixer->SetVolume(mMixer->GetMasterElement(),lNewValue);
        mValue=lNewValue;
        mBar->Refresh();
    }
}

void CAudioItem::OnVolumeMute()
{
    mMixer->SetMute(mMixer->GetMasterElement(),!mMuted);
    mMuted=!mMuted;
    mBar->Refresh();
    
}

/*namespace bdesktop*/ } /*namespace buola*/ }
